package com.eastcom.collection.tools.file


import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory;
import org.codehaus.groovy.tools.FileSystemCompiler

import com.eastcom.collection.*
import com.eastcom.collection.config.GroovyScript
/**
 * Created by yuanyue on 2014-08-07.
 */
class GroovyUtil {
	private static ConcurrentHashMap<String, Long> clazzFileTime = new ConcurrentHashMap<String, Long>()
	private static Log logger = LogFactory.getLog(GroovyUtil.class)
	private static List<String> pathList = new ArrayList()
	private static ConcurrentHashMap<String,GroovyObject> scriptCacheObject = new ConcurrentHashMap<String, GroovyObject>()
	public static List<Object> InvokeGroovyShells(String[] pathes, String[] shells, Object[] paramValues) {
		pathes.each {
			if (!pathList.contains(it)) {
				pathList.add(it)
			}
		}
		String[] pathArr = new String[pathList.size()]
		int n = 0
		pathList.each {
			pathArr[n++] = it
		}
		GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(pathArr)
		List<Object> resultList = new ArrayList()
		for (int i = 0; i < shells.length; i++) {
			String shell = shells[i]
			Object paramValue = null
			if (paramValues != null && i < paramValues.length) {
				paramValue = paramValues[i]
			}
			Binding binding = new Binding()
			binding.setVariable("args", paramValue)
			//            groovyScriptEngine.getConfig().scriptExtensions.add(shell[i])
			Object res = groovyScriptEngine.run(shell, binding)
			resultList.add(res)
		}
		return resultList
	}

	public static List<Object> InvokeGroovyShells(List<GroovyScript> scriptList) {
		List<String> pathList = new ArrayList()
		scriptList.each {
			if (!pathList.contains(it.scriptFileRootPath)) {
				pathList.add(it.scriptFileRootPath)
			}
		}
		String[] pathes = new String[pathList.size()]
		int a = 0;
		pathList.each {
			pathes[a] = it
			a++
		}
		println pathes[0]
		println pathes.length
		//        classLoader.loadClass()
		GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(pathes)
		List<Object> resultList = new ArrayList()
		for (int i = 0; i < scriptList.size(); i++) {
			GroovyScript shell = scriptList[i]
			Object paramValue = shell.param
			Binding binding = new Binding()
			binding.setVariable("args", paramValue)
			//            groovyScriptEngine.getConfig().scriptExtensions.add(shell[i])
			println shell.scriptFileName
			Object res = groovyScriptEngine.run(shell.scriptFileName, binding)
			//            groovyScriptEngine.invokeMethod()
			resultList.add(res)
		}
		return resultList
	}

	private static Class loadScriptClass(String classPath) {
		Class<?> groovyClass = null;
		GroovyClassLoader classLoader = new GroovyClassLoader(Launcher.class.getClassLoader())
		File file = null
		file = new File(classPath)
		if(!file.isFile()){
			logger.error("脚本["+classPath+"]找不到！")
			return null
		}
		long time = file.lastModified()
		println time
		//先从缓存里面去Class文件
		if(clazzFileTime.containsKey(classPath)){
			Long oldTime = clazzFileTime.get(classPath)
			if(oldTime == time){
				groovyClass = GroovyScriptClassCache.newInstance().getClassByKey(classPath)
				return groovyClass
			}
		}
		GroovyCodeSource code = new GroovyCodeSource(file,"UTF-8")
		groovyClass = classLoader.parseClass(code, true)
		println "创建新的脚本类["+groovyClass+"]"
		logger.debug("创建新的脚本类["+groovyClass+"]")
		println "加载脚本文件["+classPath+"]"
		logger.debug("加载脚本文件["+classPath+"]")
		GroovyScriptClassCache.newInstance().putClass(classPath, groovyClass)
		clazzFileTime.put(classPath, time)
		scriptCacheObject.remove(groovyClass.getName())
		return groovyClass
	}

	public static GroovyObject loadScriptObject(String classPath, boolean cached) {
		GroovyObject clazzObj
		Class<?> clazz = loadScriptClass(classPath)
		if(cached){
			if(scriptCacheObject.containsKey(clazz.getName())){
				return scriptCacheObject.get(clazz.getName())
			}
			clazzObj = (GroovyObject)clazz.newInstance()
			scriptCacheObject.put(clazz.getName(), clazzObj)
		}else{
			clazzObj = (GroovyObject)clazz.newInstance()
		}
		return clazzObj
	}
}